package com.zbkj.service.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.common.constants.CouponConstants;
import com.zbkj.common.exception.AppException;
import com.zbkj.common.model.coupon.CouponProduct;
import com.zbkj.common.model.member.PaidMemberCard;
import com.zbkj.common.model.member.PaidMemberCardProduct;
import com.zbkj.common.request.PaidMemberCardSaveRequest;
import com.zbkj.common.request.PaidMemberCardSearchRequest;
import com.zbkj.common.response.PaidMemberCardResponse;
import com.zbkj.common.response.SvipCardResponse;
import com.zbkj.common.result.CommonResultCode;
import com.zbkj.common.result.MemberResultCode;
import com.zbkj.common.utils.CrmebUtil;
import com.zbkj.service.dao.PaidMemberCardDao;
import com.zbkj.service.dao.zfbadminregion.PaidMemberCardProductDao;
import com.zbkj.service.service.PaidMemberCardProductService;
import com.zbkj.service.service.PaidMemberCardService;
import com.zbkj.service.service.UserBalanceRecordService;
import com.zbkj.service.util.BrandUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
* @author hzw
* @description PaidMemberCardServiceImpl 接口实现
* @date 2024-05-10
*/
@Service
public class PaidMemberCardServiceImpl extends ServiceImpl<PaidMemberCardDao, PaidMemberCard> implements PaidMemberCardService {

    @Resource
    private PaidMemberCardDao dao;
    @Autowired
    private UserBalanceRecordService userBalanceRecordService;
    @Autowired
    private PaidMemberCardProductService paidMemberCardProductService;


    /**
     * 添加付费会员卡
     */
    @Transactional
    @Override
    public Boolean add(PaidMemberCardSaveRequest request) {
        if (request.getType() <= 1) {
            if (ObjectUtil.isNull(request.getDeadlineDay()) || request.getDeadlineDay() < 1 || request.getDeadlineDay() > 9999) {
                throw new AppException(CommonResultCode.VALIDATE_FAILED, "期限天数范围为：1~9999");
            }
        }
        PaidMemberCard card = new PaidMemberCard();
        card.setName(request.getName());
        if (StrUtil.isNotBlank(request.getLabel())) {
            card.setLabel(request.getLabel());
        }
        card.setType(request.getType());
        card.setDeadlineDay(request.getType() > 1 ? 0 : request.getDeadlineDay());
        card.setOriginalPrice(request.getOriginalPrice());
        card.setPrice(request.getPrice());
        card.setIsFirstChargeGive(request.getIsFirstChargeGive());
        card.setGiftBalance(request.getGiftBalance());
        card.setSort(request.getSort());
        card.setStatus(request.getStatus());
        card.setBrandId(BrandUtil.getBrandIdByUrl());
        card.setUseLimit(request.getUseLimit());
        card.setUseLimitNum(request.getUseLimitNum());
        card.setUseLimitScale(request.getUseLimitScale());
        card.setRebateLimit(request.getRebateLimit());
        card.setRebateNum(request.getRebateNum());
        card.setDiscount(request.getDiscount());
        card.setIsUseShareLimit(request.getIsUseShareLimit());
        card.setIsRebateShareLimit(request.getIsRebateShareLimit());
        card.setUseShareLimitNum(request.getUseShareLimitNum());
        card.setRebateShareLimitNum(request.getRebateShareLimitNum());
        card.setIsCrossBrand(request.getIsCrossBrand());
        //card.setCategory(request.getCategory());
        boolean status = save(card);
        //后续加
 /*       if (status && request.getCategory().equals(CouponConstants.COUPON_CATEGORY_PRODUCT)){
                String productIds = request.getLinkedData();
                List<PaidMemberCardProduct> paidMemberCardProducts = new ArrayList<>();
                List<Integer> productIdList = CrmebUtil.stringToArray(productIds);
                productIdList.forEach(pid -> {
                    PaidMemberCardProduct product = new PaidMemberCardProduct();
                    product.setProductId(pid);
                    product.setCardId(card.getId());
                    paidMemberCardProducts.add(product);
                });
            paidMemberCardProductService.saveBatch( paidMemberCardProducts);
        }*/
        return status;
    }

    /**
     * 编辑付费会员卡
     */
    @Override
    public Boolean edit(PaidMemberCardSaveRequest request) {
        if (ObjectUtil.isNull(request.getId())) {
            throw new AppException(CommonResultCode.VALIDATE_FAILED, "会员卡ID不能为空");
        }
        PaidMemberCard card = getByIdException(request.getId());
        if (card.getType() <= 1) {
            if (ObjectUtil.isNull(request.getDeadlineDay()) || request.getDeadlineDay() < 1 || request.getDeadlineDay() > 9999) {
                throw new AppException(CommonResultCode.VALIDATE_FAILED, "期限天数范围为：1~9999");
            }
        }
        Integer brandId = BrandUtil.getBrandIdByUrl();
        if (!card.getBrandId().equals(brandId)) {
            throw new AppException("无法操作该记录");
        }
        card.setName(request.getName());
        card.setLabel(StrUtil.isNotBlank(request.getLabel()) ? request.getLabel() : "");
        card.setDeadlineDay(card.getType() > 1 ? 0 : request.getDeadlineDay());
        card.setOriginalPrice(request.getOriginalPrice());
        card.setPrice(request.getPrice());
        card.setIsFirstChargeGive(request.getIsFirstChargeGive());
        card.setGiftBalance(request.getGiftBalance());
        card.setSort(request.getSort());
        card.setStatus(request.getStatus());
        card.setUseLimit(request.getUseLimit());
        card.setUseLimitNum(request.getUseLimitNum());
        card.setUseLimitScale(request.getUseLimitScale());
        card.setRebateLimit(request.getRebateLimit());
        card.setRebateNum(request.getRebateNum());
        card.setDiscount(request.getDiscount());
        card.setIsUseShareLimit(request.getIsUseShareLimit());
        card.setIsRebateShareLimit(request.getIsRebateShareLimit());
        card.setUseShareLimitNum(request.getUseShareLimitNum());
        card.setRebateShareLimitNum(request.getRebateShareLimitNum());
        card.setIsCrossBrand(request.getIsCrossBrand());
        return updateById(card);
    }

    /**
     * 付费会员卡开关
     */
    @Override
    public Boolean editSwitch(Integer id) {
        Integer brandId = BrandUtil.getBrandIdByUrl();
        PaidMemberCard card = getByIdException(id);
        if (!card.getBrandId().equals(brandId)) {
            throw new AppException("无法操作该记录");
        }
        LambdaUpdateWrapper<PaidMemberCard> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(PaidMemberCard::getStatus, !card.getStatus());
        wrapper.eq(PaidMemberCard::getId, id);
        return update(wrapper);
    }

    /**
     * 删除付费会员卡
     */
    @Override
    public Boolean deleteCard(Integer id) {
        Integer brandId = BrandUtil.getBrandIdByUrl();
        PaidMemberCard card = getByIdException(id);
        if (!card.getBrandId().equals(brandId)) {
            throw new AppException("无法操作该记录");
        }
        card.setIsDelete(true);
        return updateById(card);
    }

    /**
     * 付费会员卡列表
     */
    @Override
    public List<PaidMemberCardResponse> findPlatList(PaidMemberCardSearchRequest request) {
        String name = "";
        if (StrUtil.isNotBlank(request.getName())) {
            name = URLUtil.decode(request.getName());
        }
        List<PaidMemberCard> list = findListBrand(name, ObjectUtil.isNotNull(request.getType()) ? request.getType() : null, ObjectUtil.isNotNull(request.getStatus()) ? request.getStatus() : null);
        List<PaidMemberCardResponse> responseList = new ArrayList<>();
        for (PaidMemberCard card : list) {
            PaidMemberCardResponse response = new PaidMemberCardResponse();
            BeanUtils.copyProperties(card, response);
            responseList.add(response);
        }
        return responseList;
    }

    private List<PaidMemberCard> findList(String name, Integer type, Boolean status) {
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        if (StrUtil.isNotBlank(name)) {
            lqw.like(PaidMemberCard::getName, name);
        }
        if (ObjectUtil.isNotNull(type)) {
            lqw.eq(PaidMemberCard::getType, type);
        }
        if (ObjectUtil.isNotNull(status)) {
            lqw.eq(PaidMemberCard::getStatus, status);
        }
        lqw.orderByDesc(PaidMemberCard::getSort, PaidMemberCard::getId);
        return dao.selectList(lqw);
    }

    private List<PaidMemberCard> findListBrand(String name, Integer type, Boolean status) {
        Integer brandId = BrandUtil.getBrandIdByUrl();
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        lqw.eq(PaidMemberCard::getBrandId, brandId);
        if (StrUtil.isNotBlank(name)) {
            lqw.like(PaidMemberCard::getName, name);
        }
        if (ObjectUtil.isNotNull(type)) {
            lqw.eq(PaidMemberCard::getType, type);
        }
        if (ObjectUtil.isNotNull(status)) {
            lqw.eq(PaidMemberCard::getStatus, status);
        }
        lqw.orderByDesc(PaidMemberCard::getSort, PaidMemberCard::getId);
        return dao.selectList(lqw);
    }

    @Override
    public PaidMemberCard getByIdException(Integer id) {
        PaidMemberCard paidMemberCard = getById(id);
        if (ObjectUtil.isNull(paidMemberCard) || paidMemberCard.getIsDelete()) {
            throw new AppException(MemberResultCode.PAID_MEMBER_CARD_NOT_EXIST);
        }
        return paidMemberCard;
    }

    /**
     * 付费会员卡列表(移动端)
     */
    @Override
    public List<SvipCardResponse> findFrontList(Boolean isPayTrial, Integer brandIdByUrl) {
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        if (isPayTrial) {
            lqw.in(PaidMemberCard::getType, 1, 2);
        }
        lqw.eq(PaidMemberCard::getStatus, 1);
        lqw.eq(PaidMemberCard::getBrandId, brandIdByUrl);
        lqw.orderByDesc(PaidMemberCard::getSort, PaidMemberCard::getId);
        List<PaidMemberCard> list = dao.selectList(lqw);
        List<SvipCardResponse> responseList = new ArrayList<>();
        for (PaidMemberCard card : list) {
            SvipCardResponse response = new SvipCardResponse();
            BeanUtils.copyProperties(card, response);
            responseList.add(response);
        }
        return responseList;
    }

    @Override
    public Map<String, String> getRule(PaidMemberCard paidMemberCard, Integer userId) {
        Map<String, String> map = new HashMap<>();
        if (paidMemberCard.getUseLimit() == null || paidMemberCard.getUseLimit() == 0) {
            map.put("rule", "无限制");
            map.put("amount", "0");
            return map;
        }
        String rule = "";
        BigDecimal bigDecimal = BigDecimal.ZERO;
        // 需分3次消费，每次可消费100元
        // 需分3天消费，每天可消费100元
        switch (paidMemberCard.getUseLimit()) {
            case 1:
                rule = "需分{}次消费，每次可消费:{}元";
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                rule = StrUtil.format(rule, paidMemberCard.getUseLimitNum(), bigDecimal);
                break;
            case 2:
                rule = "需分{}天消费，每天可消费:{}元，今日已消费:{}元";
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                BigDecimal today = userBalanceRecordService.getTodayConsumeAmount(userId);
                rule = StrUtil.format(rule, paidMemberCard.getUseLimitNum(), bigDecimal, today);
                break;
            case 3:
                rule = "需分{}周消费，每周可消费:{}元，本周已消费:{}元";
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                BigDecimal week = userBalanceRecordService.getWeekConsumeAmount(userId);
                rule = StrUtil.format(rule, paidMemberCard.getUseLimitNum(), bigDecimal, week);
                break;
            case 4:
                rule = "需分{}月消费，每月可消费:{}元，本月已消费:{}元";
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                BigDecimal month = userBalanceRecordService.getMonthConsumeAmount(userId);
                rule = StrUtil.format(rule, paidMemberCard.getUseLimitNum(), bigDecimal, month);
                break;
        }
        map.put("rule", rule);
        map.put("amount", bigDecimal.toString());
        return map;
    }

    @Override
    public BigDecimal getAmount(PaidMemberCard paidMemberCard, Integer userId) {
        if (paidMemberCard.getUseLimit() == null || paidMemberCard.getUseLimit() == 0) {
            return null;
        }
        BigDecimal bigDecimal = BigDecimal.ZERO;
        switch (paidMemberCard.getUseLimit()) {
            case 1:
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                break;
            case 2:
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                break;
            case 3:
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                break;
            case 4:
                bigDecimal = paidMemberCard.getGiftBalance().divide(new BigDecimal(paidMemberCard.getUseLimitNum().toString()), 2, BigDecimal.ROUND_HALF_UP);
                break;
        }
        return bigDecimal;
    }

    @Override
    public List<PaidMemberCard> getAllList() {
        Integer brandId = BrandUtil.getBrandIdByUrl();
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.select(PaidMemberCard::getId, PaidMemberCard::getName);
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        lqw.eq(PaidMemberCard::getBrandId, brandId);
        lqw.eq(PaidMemberCard::getStatus, true);
        lqw.orderByDesc(PaidMemberCard::getSort, PaidMemberCard::getId);
        return dao.selectList(lqw);
    }
    @Override
    public List<PaidMemberCard> getAllList(Integer brandId) {
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.select(PaidMemberCard::getId, PaidMemberCard::getName);
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        lqw.eq(PaidMemberCard::getBrandId, brandId);
        lqw.eq(PaidMemberCard::getStatus, true);
        lqw.orderByDesc(PaidMemberCard::getSort, PaidMemberCard::getId);
        return dao.selectList(lqw);
    }
    @Override
    public List<PaidMemberCard> getSvipList(boolean isDiscount) {
        Integer brandId = BrandUtil.getBrandIdByUrl();
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.select(PaidMemberCard::getId, PaidMemberCard::getName, PaidMemberCard::getDiscount);
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        lqw.eq(PaidMemberCard::getBrandId, brandId);
        lqw.eq(PaidMemberCard::getStatus, true);
        if (isDiscount) {
            lqw.gt(PaidMemberCard::getDiscount, 0);
        }
        lqw.orderByDesc(PaidMemberCard::getSort, PaidMemberCard::getId);
        return dao.selectList(lqw);
    }
    @Override
    public List<PaidMemberCard> getSvipListAll(boolean isDiscount, Set<Integer> bandIds) {
       // Integer brandId = BrandUtil.getBrandIdByUrl();
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.select(PaidMemberCard::getId, PaidMemberCard::getName, PaidMemberCard::getDiscount, PaidMemberCard::getBrandId);
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        lqw.in(PaidMemberCard::getBrandId, bandIds);
        lqw.eq(PaidMemberCard::getStatus, true);
        if (isDiscount) {
            lqw.gt(PaidMemberCard::getDiscount, 0);
        }
        lqw.orderByDesc(PaidMemberCard::getSort, PaidMemberCard::getId);
        return dao.selectList(lqw);
    }
    @Override
    public PaidMemberCard getDiscountInfoById(int id) {
        Integer brandId = BrandUtil.getBrandIdByUrl();
        LambdaQueryWrapper<PaidMemberCard> lqw = Wrappers.lambdaQuery();
        lqw.select(PaidMemberCard::getId, PaidMemberCard::getName, PaidMemberCard::getDiscount);
        lqw.eq(PaidMemberCard::getIsDelete, 0);
        lqw.eq(PaidMemberCard::getBrandId, brandId);
        lqw.gt(PaidMemberCard::getDiscount, 0);
        lqw.eq(PaidMemberCard::getId, id);
        return getOne(lqw);
    }
}

